package com.jiang.starter.web.merge;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CompletableFuture;

/**
 * 请求合并AOP代理方法
 * @see Merge
 * @see MergeExecutor
 */
@Slf4j
@Aspect
@Component
public class MergeAspect {

    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private Map<MergeExecutor<Object,Object>, BlockingQueue<Task>> executorBlockingQueueMap;

    @Around("@annotation(merge)")
    public Object around(ProceedingJoinPoint joinPoint, Merge merge) throws Throwable {

        // 获取注解信息
        Class<? extends MergeExecutor> executorClass = merge.executor();

        // 获取任务执行器和对应的定时任务队列
        MergeExecutor<Object, Object> mergeExecutor = applicationContext.getBean(executorClass);
        BlockingQueue<Task> taskQueue = executorBlockingQueueMap.get(mergeExecutor);

        // 取出参数
        Object[] args = joinPoint.getArgs();
        if(args.length == 0 || args.length > 1) {
            return new RuntimeException("请求参数个数必须为1");
        }
        Object arg = args[0];

        // 封装参数
        CompletableFuture<Object> future = new CompletableFuture<>();
        Task task = new Task(arg, future);

        // 将参数装入队列
        taskQueue.put(task);

        // 获取结果
        return future.join();
    }

}
